package cn.tianya.irock.bll;

import java.util.ArrayList;
import java.util.List;

import cn.tianya.irock.cache.AppCache;
import cn.tianya.irock.cache.ICache;
import cn.tianya.irock.core.Configuration;
import cn.tianya.irock.data.dalfactory.DataAccess;
import cn.tianya.irock.data.idal.ISearchDataProvider;
import cn.tianya.irock.data.model.Post;
import cn.tianya.irock.data.model.Thread;
import cn.tianya.irock.data.model.SearchQuery;
import cn.tianya.irock.data.model.Template;
import cn.tianya.irock.data.model.User;
import cn.tianya.irock.enums.SortOrder;
import cn.tianya.irock.enums.SortPostsBy;
import cn.tianya.irock.enums.SortTemplatesBy;
import cn.tianya.irock.enums.SortThreadsBy;
import cn.tianya.irock.enums.SortUsersBy;
import cn.tianya.irock.util.DataSet;
import cn.tianya.irock.util.TextUtils;


public class Searchs {
	private static ISearchDataProvider provider;

    static {
        provider = DataAccess.createSearchDataProvider();
    }
    
    public static DataSet<Thread> searchThread(int sectionId, String title) {
    	return searchThread(sectionId, title, null);
    }
    
    public static DataSet<Thread> searchThread(int sectionId, String title, String body) {
    	return searchThread(sectionId, title, body, true);
    }
    
    public static DataSet<Thread> searchThread(int sectionId, String title, String body, boolean cacheable) {
    	return searchThread(sectionId, title, body, SortThreadsBy.PostDate, SortOrder.Descending, 1, Configuration.config().getDataPageSize(), true);
    }
       
    public static DataSet<Thread> searchThread(int sectionId, String title, String body, SortThreadsBy sortBy, SortOrder sortOrder, int pageIndex, int pageSize, boolean cacheable) {
    	ArrayList<Integer>  sectionsToSearch = null;
    	
    	sectionsToSearch = new ArrayList<Integer>();
    	sectionsToSearch.add(sectionId);
		 

    	List<SearchQuery> querys = null;
    	SearchQuery query = null;
    	
    	querys = new ArrayList<SearchQuery>();
    	
    	query = new SearchQuery("subject", title);
		querys.add(query);
		
		if (!TextUtils.isEmpty(body)) {
			query = new SearchQuery("body", body);
			querys.add(query);
		}
		return searchThread(sectionsToSearch, querys, sortBy, sortOrder, pageIndex, pageSize, cacheable);
    }
    
    @SuppressWarnings("unchecked")
	protected static DataSet<Thread> searchThread(List<Integer> sectionsToSearch, List<SearchQuery> querys, SortThreadsBy sortBy, SortOrder sortOrder, int pageIndex, int pageSize, boolean cacheable) {
    	String key = "search:threads_" + sortBy + "_" + sortOrder + "_p:" + pageIndex + "_s:" + pageSize;
		DataSet<Thread> datas = null;
		
		if (cacheable) {
			for(Integer sid:sectionsToSearch) {
				key += "_" + sid;
			}
			for(SearchQuery query:querys) {
				key += "_" + query.getField() + ":" + query.getValue();
			}
			datas = (DataSet<Thread>)AppCache.get(key);
		}
		
		if (datas == null) {
			datas = provider.searchThread(sectionsToSearch, querys, sortBy, sortOrder, pageIndex, pageSize);
			if (cacheable) {
				AppCache.add(key, datas, ICache.SECOND_FACTOR);
			}
		}
		return datas;
    }
    
    public static DataSet<Post> searchPost(int sectionId, int userId, SortPostsBy sortBy, SortOrder sortOrder, int pageIndex, int pageSize, boolean cacheable) {
    	return searchPost(sectionId, 0, userId, sortBy, sortOrder, pageIndex, pageSize, cacheable);
    }
    
    public static DataSet<Post> searchPost(int sectionId, int threadId, int userId, SortPostsBy sortBy, SortOrder sortOrder, int pageIndex, int pageSize, boolean cacheable) {
    	List<SearchQuery> querys = null;
    	SearchQuery query = null;
    	ArrayList<Integer> sectionsToSearch = null;
    	
    	sectionsToSearch = new ArrayList<Integer>();
    	sectionsToSearch.add(sectionId);
    	
    	querys = new ArrayList<SearchQuery>();
    	query = new SearchQuery("userId", userId, SearchQuery.EQUALS, SearchQuery.AND);
		querys.add(query);
		
		if (threadId != 0) {
	    	query = new SearchQuery("threadId", threadId, SearchQuery.EQUALS, SearchQuery.AND);
			querys.add(query);
		}
				    	
		return searchPost(sectionsToSearch, querys, sortBy, sortOrder, pageIndex, pageSize, cacheable);
    }
    
    public static DataSet<Post> searchPost(int sectionId, String word, SortPostsBy sortBy, SortOrder sortOrder, int pageIndex, int pageSize, boolean cacheable) {
    	ArrayList<Integer> sectionsToSearch = null;
    	
    	sectionsToSearch = new ArrayList<Integer>();
    	sectionsToSearch.add(sectionId);
    	
    	return searchPost(sectionsToSearch, word, sortBy, sortOrder, pageIndex, pageSize, cacheable);
    }
        
    public static DataSet<Post> searchPost(List<Integer> sectionsToSearch, String word, SortPostsBy sortBy, SortOrder sortOrder, int pageIndex, int pageSize, boolean cacheable) {
    	List<SearchQuery> querys = null;
    	SearchQuery query = null;
    	
    	querys = new ArrayList<SearchQuery>();
    	query = new SearchQuery("subject", word);
		querys.add(query);
		
		query = new SearchQuery("body", word);
		querys.add(query);
		
		return searchPost(sectionsToSearch, querys, sortBy, sortOrder, pageIndex, pageSize, cacheable);
    }
    
    @SuppressWarnings("unchecked")
	protected static DataSet<Post> searchPost(List<Integer> sectionsToSearch, List<SearchQuery> querys, SortPostsBy sortBy, SortOrder sortOrder, int pageIndex, int pageSize, boolean cacheable) {
		String key = "search:posts_" + sortBy + "_" + sortOrder + "_p:" + pageIndex + "_s:" + pageSize;
		DataSet<Post> datas = null;
		
		if (cacheable) {
			for(Integer sid:sectionsToSearch) {
				key += "_" + sid;
			}
			for(SearchQuery query:querys) {
				key += "_" + query.getField() + ":" + query.getValue();
			}
			datas = (DataSet<Post>)AppCache.get(key);
		}
		
		if (datas == null) {
			datas = provider.searchPost(sectionsToSearch, querys, sortBy, sortOrder, pageIndex, pageSize);
			if (cacheable) {
				AppCache.add(key, datas, ICache.SECOND_FACTOR);
			}
		}
		return datas;
	}
    
    public static DataSet<User> searchUser(String name) {
    	return searchUser(name, true);
    }
    
    public static DataSet<User> searchUser(String name, boolean cacheable) {
    	return searchUser(name, SortUsersBy.LastUser, SortOrder.Descending, 1, Configuration.config().getDataPageSize(), true);
    }
    
    public static DataSet<User> searchUser(String name, SortUsersBy sortBy, SortOrder sortOrder, int pageIndex, int pageSize, boolean cacheable) {
    	List<SearchQuery> querys = new ArrayList<SearchQuery>();
		SearchQuery query = new SearchQuery("username", name);		
		querys.add(query);
		
    	return searchUser(querys, sortBy, SortOrder.Descending, pageIndex, pageSize, true);
    }
    
    @SuppressWarnings("unchecked")
	protected static DataSet<User> searchUser(List<SearchQuery> querys, SortUsersBy sortBy, SortOrder sortOrder, int pageIndex, int pageSize, boolean cacheable) {
    	String key = "search:users_" + sortBy + "_" + sortOrder + "_p:" + pageIndex + "_s:" + pageSize;
		DataSet<User> datas = null;
		
		if (cacheable) {
			for(SearchQuery query:querys) {
				key += "_" + query.getField() + ":" + query.getValue();
			}
			datas = (DataSet<User>)AppCache.get(key);
		}
		
		if (datas == null) {
			datas = provider.searchUser(querys, sortBy, sortOrder, pageIndex, pageSize);
			if (cacheable) {
				AppCache.add(key, datas, ICache.SECOND_FACTOR);
			}
		}
		return datas;
    }
	
	public static DataSet<Template> searchTemplate(String name) {
		return searchTemplate(name, true);
	}
			
	public static DataSet<Template> searchTemplate(String name, boolean cacheable) {
		return searchTemplate(name, SortTemplatesBy.LastTemplate, SortOrder.Descending, 1, Configuration.config().getDataPageSize(), true);
	}
		
	public static DataSet<Template> searchTemplate(String name, SortTemplatesBy sortBy, SortOrder sortOrder, int pageIndex, int pageSize, boolean cacheable) {
		List<SearchQuery> querys = new ArrayList<SearchQuery>();
		SearchQuery query = new SearchQuery("name", name);
		querys.add(query);
		
		return searchTemplate(querys, sortBy, sortOrder, cacheable, pageIndex, pageSize);
	}
	
	@SuppressWarnings("unchecked")
	protected static DataSet<Template> searchTemplate(List<SearchQuery> querys, SortTemplatesBy sortBy, SortOrder sortOrder, boolean cacheable, int pageIndex, int pageSize) {
		String key = "search:templates_" + sortBy + "_" + sortOrder + "_p:" + pageIndex + "_s:" + pageSize;
		DataSet<Template> datas = null;
		
		if (cacheable) {
			for(SearchQuery query:querys) {
				key += "_" + query.getField() + ":" + query.getValue();
			}
			datas = (DataSet<Template>)AppCache.get(key);
		}
		
		if (datas == null) {
			datas = provider.searchTemplate(querys, sortBy, sortOrder, pageIndex, pageSize);
			if (cacheable) {
				AppCache.add(key, datas, ICache.SECOND_FACTOR);
			}
		}
		return datas;
	}
}
